Skip to content

Docs: site revamp (rounds 1-6) — themed Starlight site with story, architecture, cheat sheet, command preambles#39

Merged
lliWcWill merged 20 commits into
masterfrom
docs/site-revamp
Apr 30, 2026
Merged

Docs: site revamp (rounds 1-6) — themed Starlight site with story, architecture, cheat sheet, command preambles#39
lliWcWill merged 20 commits into
masterfrom
docs/site-revamp

Conversation

@lliWcWill
Copy link
Copy Markdown
Owner

Summary

Six rounds of Claude Design's docs-site revamp, cherry-picked clean off the media-feature branch (#38) so each PR can be reviewed against its own surface area.

  • Round 1 — CAVE theme + per-page Copy/Open-in-LLM dropdown (PageActions.astro, PageTitle.astro, [...slug].md.ts raw-markdown endpoint, 38→761 line custom.css base)
  • Round 2 — Landing page rebuild with keystone-emphasis chain diagram, native-vs-fsuite block, drone sensor hero
  • Round 3 — Monokai terminal blocks, full agent-scrapeable cheat sheet at /reference/cheatsheet/, MCP-sequential limitation note + fbash escape-hatch
  • Round 4 — 14 per-command drone-profile preambles above the existing build-time --help output (fmap explicitly tagged KEYSTONE)
  • Round 5/architecture/ overview page (NEW), MCP/Hooks/Telemetry pillar pages rebuilt, first-contact polish, Agent→Hooks→MCP→CLI→Telemetry delivery flow diagram
  • Round 6 — Story-page rebuild: Episodes 1/2/3 + Lightbulb get HUD frames, status strips, chain-display row, carrier/cargo stack metaphor (Episode 0 untouched)

Stats

38 files changed, 4502 insertions(+), 1206 deletions(-)

Test plan

  • All 14 /commands/<TOOL>/ pages → HTTP 200 with drone profile rendering
  • All 5 story pages (episode-0/1/2/3/lightbulb) → 200 with HUD frames on episodes 1-3 + lightbulb
  • /architecture/, /architecture/mcp/, /hooks/, /telemetry/, /chains/ → 200 with delivery-flow diagram on the index
  • /reference/cheatsheet/ → 200, every tool anchor (#fs, #fmap, etc.) reachable
  • /getting-started/first-contact/ → 200 with monokai ftree sample
  • Per-page Copy-Markdown / Open-in-Claude / Open-in-ChatGPT dropdown wired via [...slug].md.ts raw endpoint
  • GitHub Pages preview build clean (will run on this PR)

MDX strict-mode lessons absorbed across rounds (recorded in commit messages)

Trigger Fix
Bare { } in <pre> Escape to \{ \} or &#123; &#125;
Blank line inside <pre> Replace with <span class=\"tk-mut\">·</span> separator
Paired * chars inside <pre> (e.g. *.ts × 2) trigger emphasis Escape to &#42;
4+ leading spaces inside <pre> trigger CommonMark indented-code-block Replace with &nbsp; × N
<pre> followed by <span> on same line breaks MDX 2 strict Split <pre> to its own line
Unquoted : in YAML frontmatter description Quote the value

Notes

CAVE theme (custom.css):
- Bioluminescent green accent (#3aff9d) on void-black
- Geist + JetBrains Mono fonts
- Sidebar tool prefixes (fs, ft, fl…), CAVE footer chip, themed code blocks
- Designed by Claude Design; wired in by overlaying real Starlight DOM
- Old custom.css preserved as custom_backup.css for rollback safety

Page actions widget (mirrors Anthropic/Mintlify 'Copy page' dropdown):
- Inline with the page H1, top-right of every doc (hidden on splash hero)
- Pill button: 'Copy page' (fetches .md, writes to clipboard) + caret toggle
- Dropdown items:
    · Copy as Markdown — page source for LLMs
    · Copy as plain text — rendered body
    · View as Markdown — opens .md in new tab
    · Open in Claude — claude.ai/new?q=<encoded prompt + markdown>
    · Open in ChatGPT — chatgpt.com/?hints=search&q=<same>
    · View source on GitHub — direct link to the source MDX
- Vanilla DOM controller, no framework deps
- ARIA: real menuitem roles, Escape closes, click-outside closes, keyboard nav
- CAVE-themed: matches button border, accent green on hover, animated open

Markdown endpoint (src/pages/[...slug].md.ts):
- Astro endpoint enumerated via getStaticPaths from the docs collection
- Returns YAML frontmatter (title, description) + raw body as text/markdown
- Cache-Control: 5 minutes
- Powers Copy/View/Open actions; safe for LLM consumption

Wired via Starlight component override in astro.config.mjs:
  components: { PageTitle: './src/components/PageTitle.astro' }

Validated locally:
- All 6 menu items render with correct data-action attrs
- /fsuite/<slug>.md returns HTTP 200, content-type text/markdown
- GitHub source URL points to ./site/src/content/docs/<slug>.mdx
- Hot-reload working through dev server
…sensor hero

- Append Claude Design's component appendix CSS (459 lines) to custom.css
  for Field Dispatch strip, counter strip, keystone pipeline diagram,
  native-vs-fsuite comparison, drone-cave sensor diagram, fcase lifecycle
- Replace landing page (index.mdx): adds Field Dispatch strip, counters,
  native-vs-fsuite ~12k vs ~480 token cost comparison, keystone pipeline
  with fs as front door + fmap as the visual keystone, 'see it in the
  wild' 4-call walkthrough, Claude Code self-assessment quote
- Replace mental-model.md: drone-cave sensor diagram with 3 hovering
  drones over directory tree, keystone pipeline, why fmap matters as
  the gap native CLI doesn't fill, native->fsuite reflex translation
- Replace chains.md: Core/Investigation/Debugging/Refactoring/Binary
  chains plus the fcase lifecycle as state-machine block

MDX fixes applied during integration:
- Escape literal { } in <pre> JSON sample (line 125: \{ \}) so MDX
  doesn't parse them as JSX expressions
- Split <pre> opening tag onto its own line and replace blank-line
  paragraph breaks inside <pre> blocks with <span class='fs-c-sep'>
  separators — MDX 2+ requires HTML elements to be a contiguous block,
  blank lines terminate the paragraph and orphan the opening tag
  (confirmed via mdx-js maintainer guidance + Astro Starlight docs)
…tial note

Claude Design deliverable v3:
- custom.css: +209 lines (sections 30-34: .fs-term monokai block with traffic-light
  bar + cost meter, .tk-* token palette, .fs-drone profile cards, .fs-cheat-nav
  sticky tool jumps, .fs-mcp-note amber callout, .fs-footer-status)
- reference/cheatsheet.mdx: new 536-line agent-scrapeable single-page reference,
  one drone profile + commands table + monokai terminal sample per tool,
  canonical pipelines + MCP-vs-CLI semantics table at the bottom
- architecture/chains.md: rebuilt from chain-combinations spec — pipe contract
  (producers/consumers/non-pipe), 2/3/4-cmd chain examples, 5 investigation
  patterns, fcase lifecycle, invalid-chains-and-why, MCP-sequential note with
  fbash escape-hatch tip
- old reference/cheatsheet.md removed (URL slug now served by .mdx)

MDX strict-mode fixes applied to cheatsheet.mdx before write: 20 bare {/}
chars escaped to \{ \} inside <pre> blocks (TS imports + function bodies);
8 blank lines inside <pre> replaced with <span class="tk-mut">·</span>
separators. Verified clean — all 5 affected pages return 200 with zero MDX
compile errors in dev log.
…nal samples

Claude Design deliverable v4: 14 preamble blocks, one per fsuite tool,
inserted above the existing `## Help output` heading on each commands/<TOOL>.md
page. The build-time --help block stays as the source of truth below.

Each preamble has:
- Drone profile card (codename · role · chain position · pipe behavior)
- Canonical chains (2-5 realistic pipe patterns per tool)
- Monokai terminal sample for the heavy hitters: fs, fls, fmap, fread,
  fcontent, fsearch (uses round-3's .fs-term + .tk-* classes)

Highlights:
- fmap explicitly tagged KEYSTONE with "Native CLI has nothing like it"
- fbash framed as the MCP escape hatch with concrete pipe-inside-fbash examples
- fwrite labeled MCP-only with the new-file-vs-surgical decision rule
- fcase/freplay framed as continuity tools for cross-session memory loss
- fprobe framed as the binary branch when fcontent returns nothing

MDX strict-mode: Claude Design pre-escaped braces to &#123;/&#125; entities
in <pre> blocks (learned from rounds 2-3); fixed 4 remaining blank-line-
inside-pre cases in fs.md/fls.md preambles via Python pre-pass with
<span class="tk-mut">·</span> separators. All 14 pages render at HTTP 200,
zero MDX compile errors.

No CSS this round — round 3's classes carry the visual styling.
…livery flow

Claude Design deliverable v5:
- custom.css: +88 lines (.fs-delivery flow diagram — color-coded
  Agent/Hooks/Block/MCP/Route/CLI/Exec/Telemetry/Log nodes with chain arrows
  reusing .fs-arr from rounds 3-4)
- architecture/index.mdx: NEW (80 lines) — pillars-at-a-glance overview, the
  Agent → Hooks → MCP → CLI → Telemetry delivery flow diagram, CLI-vs-MCP
  pipe semantics table, repo-paths-for-each-pillar table. Ties chains.md +
  mcp.md + hooks.md + telemetry.md together.
- architecture/mcp.md: rebuilt with drone-profile card, fbash escape-hatch
  pattern (multi-step pipe inside one MCP call), tool-list verification step
- architecture/hooks.md: rebuilt — full Read/Write/Edit/Grep/Glob → fsuite
  redirect table, exit 2 protocol explained, "why hooks + MCP together"
  reframed as complementary not redundant
- architecture/telemetry.md: rebuilt — why telemetry exists (fmetrics
  learning loop), ~/.fsuite/ storage-shape diagram, sanitization tradeoff
  reasoning from Episode 0
- getting-started/first-contact.md: drone-profile header, monokai terminal
  sample on the ftree --snapshot step, stronger "what you should notice"
  callout

MDX strict-mode: only first-contact.md had blank-line-inside-pre cases (3
fixed via tk-mut separator span). Hit a YAML frontmatter colon-collision
on architecture-index.mdx — "three pillars: MCP, hooks, telemetry." had
unquoted ': ' that the YAML parser misread as a nested mapping. Quoted the
description value to fix. All 5 affected pages return 200; dev log clean
since 14:57:40 reload.
…HUD frames, status strips, chain display

Claude Design deliverable v6:
- custom.css: +251 lines (.fs-hud + .fs-hud-glow corner-bracket frames with
  crosshair grid background; .fs-strip 5-cell status row; .fs-chain-display
  horizontal pipeline; .fs-stack 2-layer carrier/cargo metaphor block)
- story/episode-1.mdx: replaced — The Bash Overflow (grep -r node_modules
  180k-token incident → fsearch + fcontent born, 3 principles distilled)
- story/episode-2.mdx: replaced — Reading Too Much (cat handler.ts 612-line
  problem → fmap + fread --symbol born, fmap explicitly tagged KEYSTONE,
  20× reduction shown)
- story/episode-3.mdx: replaced — The Enforcement Layer (Read-used-4×-more
  telemetry moment → exit 2 hooks born, before/after 10.7× reduction sample)
- story/lightbulb.mdx: replaced — synthesis page with .fs-hud-glow halo,
  chain-display row with fmap KEYSTONE highlighted, carrier/cargo stack
- Old episode-1/2/3.md and lightbulb.md removed (URL slugs now served by
  .mdx). Episode 0 untouched.

MDX strict-mode lessons in this round:
- `*` inside <pre> opens markdown emphasis: 2 occurrences of `*.ts` per
  pre block in episode-1 paired up as italic open/close, breaking </span>
  expectations. Fixed by escaping to `&#42;`.
- Leading 4+ spaces inside <pre> trigger CommonMark indented-code-block
  rule, terminating the surrounding paragraph. Fixed in episode-2/3 with
  `&nbsp;` × N for the leading width.
- `<pre>` followed by `<span>` on the same line breaks MDX 2 strict-mode
  parsing — opener must be on its own line. Split `<pre>\n<span...` for
  episodes 1/2/3 to land all five story pages at HTTP 200.

Verified: all 5 story pages return 200, dev log clean since 15:11:29.
fs-hud × 17, fs-strip × 12, fs-term × 6, fs-chain-display × 6, fs-stack
× 12, fs-hud-glow × 4 (lightbulb only) — every new component rendering.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3d4f3205-661c-4417-93b8-bc410784b70c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Refactors documentation into MDX format with structured metadata (role, chain position, piping), canonical command examples, and narrative sections. Adds PageActions component for inline page controls (copy/view/LLM actions). Implements markdown serving endpoint. Applies comprehensive CSS theme overhaul replacing minimal tweaks with extensive styling system.

Changes

Cohort / File(s) Summary
Site Components
site/astro.config.mjs, site/src/components/PageActions.astro, site/src/components/PageTitle.astro
New PageActions component with client-side dropdown menu, markdown fetching, clipboard copy, and LLM integration. PageTitle component override integrates PageActions inline. Astro config registers PageTitle override.
Markdown Serving Route
site/src/pages/[...slug].md.ts
New API route that dynamically generates markdown source files from docs collection, emitting YAML frontmatter (title, description) plus raw body with 5-minute cache headers.
Architecture Documentation
site/src/content/docs/architecture/index.mdx, site/src/content/docs/architecture/chains.md, site/src/content/docs/architecture/hooks.md, site/src/content/docs/architecture/mcp.md, site/src/content/docs/architecture/telemetry.md
New index.mdx introducing architecture pillars (MCP adapter, hooks, telemetry, chains). Expanded chains.md with formal pipe contracts and valid chain matrices. Enhanced hooks/mcp/telemetry docs with explicit config examples, verification workflows, and clarified behavior.
Command Documentation
site/src/content/docs/commands/fbash.md, site/src/content/docs/commands/fcase.md, site/src/content/docs/commands/fcontent.md, site/src/content/docs/commands/fedit.md, site/src/content/docs/commands/fls.md, site/src/content/docs/commands/fmap.md, site/src/content/docs/commands/fmetrics.md, site/src/content/docs/commands/fprobe.md, site/src/content/docs/commands/fread.md, site/src/content/docs/commands/freplay.md, site/src/content/docs/commands/fs.md, site/src/content/docs/commands/fsearch.md, site/src/content/docs/commands/ftree.md, site/src/content/docs/commands/fwrite.md
All command docs extended with fs-drone metadata panels (role, chain position, piping), canonical chain examples, and terminal sample output. Narrative descriptions clarified on tool positioning and usage patterns.
Getting Started Documentation
site/src/content/docs/getting-started/first-contact.md, site/src/content/docs/getting-started/mental-model.md, site/src/content/docs/index.mdx
Restructured first-contact with expanded behavioral details and terminal previews. Mental-model doc adds sensor metaphor, HTML pipeline visualization, and keystone fmap emphasis. Index.mdx rewritten with FIELD DISPATCH status, tool counters, reconnaissance workflow framing, and native-vs-fsuite comparison table.
Story/Narrative Docs
site/src/content/docs/story/episode-1.mdx, site/src/content/docs/story/episode-2.mdx, site/src/content/docs/story/episode-3.mdx, site/src/content/docs/story/lightbulb.mdx
Replaced old markdown episode docs with new MDX versions. Ep1: Bash overflow incident and design response. Ep2: Symbol-mapping discipline via fmap. Ep3: Enforcement layer and hook+MCP integration. Lightbulb: Reframes fsuite as discipline delivery vehicle with visual stack/chain components.
Reference Cheatsheet
site/src/content/docs/reference/cheatsheet.md (deleted), site/src/content/docs/reference/cheatsheet.mdx
Deleted old markdown cheatsheet with one-line recipes. Added new MDX cheatsheet with structured tool role/position reference, canonical pipelines, pipe/MCP semantics documentation, and agent-scrapeable formatting.
Styling
site/src/styles/custom.css, site/src/styles/custom_backup.css
Major CSS rewrite: Replaces minimal tweaks with comprehensive CAVE theme. Rewrites Starlight tokens, adds typography, overlay glow/scanlines, restyles header/sidebar/TOC. Introduces extensive custom component classes for page actions, hero layouts, terminal rendering, drone profiles, delivery flow diagrams, and MDX narrative UI blocks. Adds custom_backup.css with Monokai color tokens.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

  • #37 — Updates telemetry documentation with caller attribution fields (model_id/agent_id/session_id) that overlap with the telemetry.md doc restructuring in this PR.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the PR scope: documentation site revamp with specific rounds addressing theming, widgets, story/architecture rebuilds, and command documentation.
Description check ✅ Passed Description clearly explains the six rounds of changes, provides stats, test plan, MDX lessons, and notes. It directly relates to the changeset and aids understanding of the PR's intent.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/site-revamp

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36053d5e2c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/components/PageActions.astro Outdated
Comment thread site/src/components/PageActions.astro Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
site/src/content/docs/commands/fwrite.md (1)

36-68: ⚠️ Potential issue | 🟠 Major

Replace the fake help block or relabel it.

This section claims to show live --help output, but the fenced content is shell-script/comment text, not help text. It also conflicts with the MCP-only note above by presenting CLI-style usage. Capture the actual help output or rename this section to match what it contains.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@site/src/content/docs/commands/fwrite.md` around lines 36 - 68, The fenced
block in site/src/content/docs/commands/fwrite.md labeled as the "live `--help`
output of `fwrite`" is actually a shell-script/comment block and not the real
help text; either replace it with the actual runtime `fwrite --help` output
captured from the tool binary (run the binary with --help and paste the raw
output into the fenced code block) or change the section heading and explanatory
text to clearly relabel it as a script/example (e.g., "example script output" or
"usage notes") so it no longer claims to be live help; ensure the surrounding
MCP-only note remains consistent with whichever option you choose and update the
fenced block content and its caption accordingly.
site/src/styles/custom_backup.css (1)

1-39: 🧹 Nitpick | 🔵 Trivial

Remove or explicitly wire this backup stylesheet.

site/src/styles/custom_backup.css is not referenced by the active Starlight config (site/astro.config.mjs only loads ./src/styles/custom.css), so this file is dead config surface and will drift.

Suggested cleanup
- site/src/styles/custom_backup.css

If you want to keep it as a theme preset, move it to docs/design notes or add an explicit toggle/import path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@site/src/styles/custom_backup.css` around lines 1 - 39, The backup stylesheet
site/src/styles/custom_backup.css is dead (not loaded by the Starlight config
which only imports ./src/styles/custom.css); either remove the unused file to
avoid config drift or explicitly wire it by adding an import reference in the
Starlight/astro config (the same place that currently loads
./src/styles/custom.css) or move it into project docs/design notes as a theme
preset; update the active config to reference custom_backup.css if you intend it
to be selectable, or delete the file and any references to CSS
variables/selectors defined there (e.g., :root overrides, code, blockquote,
table) to keep the repo clean.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@site/src/components/PageActions.astro`:
- Around line 33-39: mdRelative is being built as an absolute path
(`/${slug}.md`) which causes new URL(...) later to treat it as root-relative and
drop any subpath base; change the mdRelative construction to omit the leading
slash (use `${slug}.md` or empty string when slug falsy) so it becomes a proper
relative path resolved against the extracted base, and ensure the rest of the
logic that uses mdRelative (and ghSourcePath/ghSourceUrl) continues to handle
the empty-slug case consistently.

In `@site/src/content/docs/architecture/chains.md`:
- Around line 24-35: The “Non-pipe tools” sentence contradicts the table because
fread and fedit are listed as stdin consumers; update this section to split
tools into two clear groups: "Stdin-capable consumers" (include fcontent, fmap,
fread, fedit with their stdin behaviors and limits) and "Arg-only endpoints"
(include ftree, fprobe, fcase, freplay, fmetrics and note they take arguments
and don't accept piped path lists), and adjust the prose to state that
stdin-capable tools can be used in the middle of chains while arg-only endpoints
are chain termini; update any summary sentence and table caption in chains.md
accordingly to avoid the contradiction.

In `@site/src/content/docs/architecture/hooks.md`:
- Around line 37-53: The JSON example in the hooks documentation contains
escaped braces (\{ and \}) which makes it invalid JSON and will break
copy/paste; update the fenced code block so the object uses normal braces (e.g.
top-level "hooks" object with "PreToolUse" array, the inner object with
"matcher": "Read" and its "hooks" array containing the "command" entry) — remove
all backslashes before { and } so the PreToolUse, matcher, hooks, type, and
command fields form valid JSON.

In `@site/src/content/docs/architecture/index.mdx`:
- Around line 15-23: The "MCP Adapter" Card currently claims it "Exposes every
fsuite tool" but the MCP index module does not register all 14 tools; update the
card text (Card title="MCP Adapter") to accurately describe the actual
registered set (e.g., "Exposes the registered MCP tools: <brief list or count>")
or, if you intend full coverage, add the missing registrations to the MCP index
module's tool registration/export (look for functions/values like
registerTool(s) or the exported tool list in the mcp index module) before
keeping the current wording.

In `@site/src/content/docs/architecture/mcp.md`:
- Around line 13-31: Update the documentation to reflect the actual MCP server
surface: change the summary and "What you get" and verification prompt so they
no longer claim "all 14 fsuite tools" and instead state that only the subset
currently exposed by mcp/index.js is available, and make clear that next_hint is
emitted conditionally (only when fmetrics combo data yields a confident
recommendation) rather than guaranteed on every response; review and mirror
these edits for the equivalent section referenced around lines 84-105 so the
text, examples, and verification steps align with mcp/index.js behavior and the
conditional next_hint semantics.

In `@site/src/content/docs/architecture/telemetry.md`:
- Around line 104-110: The fenced code block in telemetry.md showing the storage
tree uses a bare triple-backtick fence which trips markdownlint; update the
opening fence from ``` to ```text so the block has a language tag (e.g., change
the code block that contains "~/.fsuite/ ..." to use ```text) to enable syntax
highlighting and satisfy the linter.

In `@site/src/content/docs/commands/fbash.md`:
- Around line 25-42: The docs incorrectly claim that environment variables
persist across fbash calls; update the fbash examples and text so they no longer
assert full shell env persistence: change the "Stateful session — cd persists to
the next call" section to explicitly state that only working directory and
case/session state are restored between invocations (e.g., "cd persists, but
exported environment variables do not"), remove or replace the `fbash "cd
/project && export DEBUG=1"` / `fbash "pwd && env | grep DEBUG"` example with a
correct example showing only cwd persistence (or add a note about the supported
explicit state-restore mechanism if one exists), and keep references to the
fbash examples and canonical chains (fbash, cd, export) so readers can find the
updated text.

In `@site/src/content/docs/commands/fcase.md`:
- Around line 49-51: The example chain uses fread with --around against a
directory, which is invalid; update the example in fcase.md so fread --around
targets a specific file rather than a directory in the pipeline that ends with "
| fcase evidence import auth-seam", i.e., replace the /project directory
argument with a concrete source file path (a single file containing the "def
auth" context) so the fread + fcase example is runnable.

In `@site/src/content/docs/commands/freplay.md`:
- Around line 44-46: The example invocation for the canonical chain is missing
the required case slug — update the example command `freplay list -o json` to
include the `<case-slug>` argument (e.g., `freplay list <case-slug> -o json`) so
it matches the documented usage `freplay list <case-slug>` in the help block;
locate the example string in the freplay list canonical chain and add the
placeholder or a realistic slug to make the example runnable.

In `@site/src/content/docs/commands/fsearch.md`:
- Around line 25-27: Update the fsearch doc text to explicitly state that piping
`fsearch -o paths` into `fread` requires the stdin flags; mention that `fread`
must be invoked with `--from-stdin --stdin-format=paths` to consume the
newline-delimited paths emitted by `fsearch -o paths` (while keeping examples
that `fmap` and `fcontent` accept the same output as appropriate). Reference the
existing symbols `fsearch`, `-o paths`, and `fread` and add the required
`--from-stdin` and `--stdin-format=paths` flags in the sentence so readers know
the exact invocation needed for piping.

In `@site/src/content/docs/commands/ftree.md`:
- Around line 29-31: The sentence about "doesn't pipe" is misleading; change the
wording to state that the ftree command does not read from stdin (it produces a
tree to provide context and is intended to be run at the start of a pipeline),
and explicitly mention that ftree can still emit machine-friendly output via the
-o paths and -o json options for downstream consumption; update the line
referring to Canonical chains to reference ftree and the -o paths/-o json flags
so readers understand the distinction between stdin behavior and output formats.

In `@site/src/content/docs/getting-started/first-contact.md`:
- Around line 33-38: The example pipes structured JSON from ftree through head,
which truncates the JSON envelope; remove the pipe to head so the command shows
the full bounded JSON output — update the example to use the ftree invocation
with the --snapshot flag and -o json option (ftree --snapshot -o json .) and
remove references to piping to head or truncation.

In `@site/src/content/docs/index.mdx`:
- Around line 63-98: The diagram incorrectly places fs as a pipe participant;
update the content in index.mdx so fs is shown as the dispatcher (separate from
the pipeline) and not inside the linear chain — move or render the
<code>fs</code> token outside the main pipeline row and keep
<code>fsearch</code>, <code>fcontent</code>, <code>fmap</code>,
<code>fread</code>, <code>fcase</code>, <code>fedit</code> as the pipe sequence,
and adjust the undernote text to state that <code>fs</code> auto-routes via
<code>fsearch</code> + <code>fcontent</code> rather than being chained directly.

In `@site/src/pages/`[...slug].md.ts:
- Around line 18-23: In getStaticPaths, normalize the docs homepage by mapping
an index entry to an empty slug instead of "/index.md": after stripping the
extension from entry.id (the current replace(/\.(md|mdx)$/i, '')), check if the
resulting name is "index" (or empty) and set params.slug to "" for the root
page; otherwise keep the stripped value. Update the mapping in getStaticPaths so
PageActions and other consumers receive "" for the homepage slug while other
entries keep their computed slug.

In `@site/src/styles/custom.css`:
- Around line 606-609: The CSS animations (e.g., `@keyframes` page-actions-menu-in
and the other keyframes around the reported ranges) run unconditionally; add a
prefers-reduced-motion media query to provide a fallback by disabling or
shortening these animations for motion-sensitive users. Specifically, wrap
overrides in `@media` (prefers-reduced-motion: reduce) { ... } and inside set the
animated elements' animation-duration/transition-duration to 0ms (or animation:
none / transition: none) for the selectors that use page-actions-menu-in and the
other keyframes so the animations are effectively removed while leaving the rest
of the styles intact.
- Line 12: Move the `@import` so it is the very first statement in custom.css and
normalize its syntax to use double quotes (e.g. `@import`
url("https://fonts.googleapis.com/…");), then fix the Stylelint keyword-case
failures by converting the offending CSS keyword values to lowercase in the
declaration blocks that triggered the errors (the rules that include the earlier
reported keyword-case issues). Ensure the `@import` uses the exact URL shown in
the diff and change any capitalized keywords in those declarations to their
lowercase form to satisfy the keyword-case rule.
- Line 12: Remove the remote `@import` that pulls Geist and JetBrains Mono and
instead self-host the font files: download the required font weights for "Geist"
and "JetBrains Mono", place them under your site's static/public fonts folder
(e.g., public/fonts/...), then replace the `@import` in custom.css with explicit
`@font-face` rules that reference the local files (include font-family names
"Geist" and "JetBrains Mono", correct src formats, weight/style declarations,
and font-display: swap). Finally ensure any uses of those families in your CSS
still reference the exact family names used in the `@font-face` rules.
- Around line 97-99: The rule setting html { color-scheme: dark; } forces dark
UA control rendering even when the site uses light theme; update the CSS to
support both schemes by using either html { color-scheme: light dark; } or add a
theme-specific override such as [data-theme="light"] html { color-scheme: light;
} (and keep html { color-scheme: dark; } for the dark theme) so native controls
render correctly depending on the active theme; adjust the selectors around the
html rule and the data-theme="light" attribute to make the switch.
- Around line 1607-1612: The mobile CSS currently removes bottom borders with
.fs-strip-cell:nth-last-child(-n+2) which clears borders for the last two items
regardless of total count (breaking 5-cell layouts); replace that rule with a
conditional selector pair that only removes the true last-row cells for a
2-column layout: use .fs-strip-cell:nth-last-child(1) to always clear the final
item and .fs-strip-cell:nth-last-child(2):nth-child(odd) to clear the
second-to-last only when the total count is even, updating the rule in the media
query that targets .fs-strip and .fs-strip-cell.

---

Outside diff comments:
In `@site/src/content/docs/commands/fwrite.md`:
- Around line 36-68: The fenced block in
site/src/content/docs/commands/fwrite.md labeled as the "live `--help` output of
`fwrite`" is actually a shell-script/comment block and not the real help text;
either replace it with the actual runtime `fwrite --help` output captured from
the tool binary (run the binary with --help and paste the raw output into the
fenced code block) or change the section heading and explanatory text to clearly
relabel it as a script/example (e.g., "example script output" or "usage notes")
so it no longer claims to be live help; ensure the surrounding MCP-only note
remains consistent with whichever option you choose and update the fenced block
content and its caption accordingly.

In `@site/src/styles/custom_backup.css`:
- Around line 1-39: The backup stylesheet site/src/styles/custom_backup.css is
dead (not loaded by the Starlight config which only imports
./src/styles/custom.css); either remove the unused file to avoid config drift or
explicitly wire it by adding an import reference in the Starlight/astro config
(the same place that currently loads ./src/styles/custom.css) or move it into
project docs/design notes as a theme preset; update the active config to
reference custom_backup.css if you intend it to be selectable, or delete the
file and any references to CSS variables/selectors defined there (e.g., :root
overrides, code, blockquote, table) to keep the repo clean.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2f55f1f7-1092-48a7-ae0d-fedf5b0f9b7e

📥 Commits

Reviewing files that changed from the base of the PR and between c745101 and 36053d5.

📒 Files selected for processing (38)
  • site/astro.config.mjs
  • site/src/components/PageActions.astro
  • site/src/components/PageTitle.astro
  • site/src/content/docs/architecture/chains.md
  • site/src/content/docs/architecture/hooks.md
  • site/src/content/docs/architecture/index.mdx
  • site/src/content/docs/architecture/mcp.md
  • site/src/content/docs/architecture/telemetry.md
  • site/src/content/docs/commands/fbash.md
  • site/src/content/docs/commands/fcase.md
  • site/src/content/docs/commands/fcontent.md
  • site/src/content/docs/commands/fedit.md
  • site/src/content/docs/commands/fls.md
  • site/src/content/docs/commands/fmap.md
  • site/src/content/docs/commands/fmetrics.md
  • site/src/content/docs/commands/fprobe.md
  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/commands/freplay.md
  • site/src/content/docs/commands/fs.md
  • site/src/content/docs/commands/fsearch.md
  • site/src/content/docs/commands/ftree.md
  • site/src/content/docs/commands/fwrite.md
  • site/src/content/docs/getting-started/first-contact.md
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/index.mdx
  • site/src/content/docs/reference/cheatsheet.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/story/episode-1.md
  • site/src/content/docs/story/episode-1.mdx
  • site/src/content/docs/story/episode-2.md
  • site/src/content/docs/story/episode-2.mdx
  • site/src/content/docs/story/episode-3.md
  • site/src/content/docs/story/episode-3.mdx
  • site/src/content/docs/story/lightbulb.md
  • site/src/content/docs/story/lightbulb.mdx
  • site/src/pages/[...slug].md.ts
  • site/src/styles/custom.css
  • site/src/styles/custom_backup.css
💤 Files with no reviewable changes (5)
  • site/src/content/docs/story/lightbulb.md
  • site/src/content/docs/reference/cheatsheet.md
  • site/src/content/docs/story/episode-3.md
  • site/src/content/docs/story/episode-1.md
  • site/src/content/docs/story/episode-2.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test-suite
🧰 Additional context used
🧠 Learnings (13)
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fs` as the default search entry point and let it auto-route to the appropriate tool

Applied to files:

  • site/src/content/docs/commands/fsearch.md
  • site/src/content/docs/commands/fs.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/story/episode-1.mdx
  • site/src/content/docs/getting-started/first-contact.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fsuite` for the suite-level mental model, then reach for operational tools (fs, ftree, fls, fsearch, fcontent, fmap, fread, fedit, fwrite, fbash, fprobe, fcase, freplay, fmetrics) for filesystem reconnaissance, bounded reading, and surgical editing

Applied to files:

  • site/src/content/docs/commands/fsearch.md
  • site/src/content/docs/commands/fls.md
  • site/src/content/docs/commands/fwrite.md
  • site/src/content/docs/commands/fprobe.md
  • site/src/content/docs/commands/fmetrics.md
  • site/src/content/docs/commands/fcase.md
  • site/src/content/docs/commands/fs.md
  • site/src/content/docs/commands/fedit.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/commands/fmap.md
  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/commands/ftree.md
  • site/src/content/docs/architecture/index.mdx
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/story/lightbulb.mdx
  • site/src/content/docs/story/episode-1.mdx
  • site/src/content/docs/story/episode-2.mdx
  • site/src/content/docs/architecture/telemetry.md
  • site/src/content/docs/architecture/chains.md
  • site/src/content/docs/architecture/mcp.md
  • site/src/content/docs/getting-started/first-contact.md
  • site/src/content/docs/commands/fbash.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Prefer `fmap` + `fread --symbol` before broad `fcontent` searches

Applied to files:

  • site/src/content/docs/commands/fsearch.md
  • site/src/content/docs/commands/fs.md
  • site/src/content/docs/commands/fcontent.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/commands/fmap.md
  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/story/episode-2.mdx
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Open `fcase init` at the start of any non-trivial investigation and close with `fcase resolve`

Applied to files:

  • site/src/content/docs/commands/fcase.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Always check `fcase find --status all --deep` before starting new work to see if past investigations have already answered the question

Applied to files:

  • site/src/content/docs/commands/fcase.md
  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/getting-started/first-contact.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fedit --function_name` for symbol-scoped edits without needing large unique context strings

Applied to files:

  • site/src/content/docs/commands/fedit.md
  • site/src/content/docs/getting-started/mental-model.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fedit --lines` when you have specific line numbers from `fread`. This provides the fastest edit mode with zero ambiguity

Applied to files:

  • site/src/content/docs/commands/fedit.md
  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/getting-started/mental-model.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Never edit blindly. Always inspect context with `fread` before calling `fedit`

Applied to files:

  • site/src/content/docs/commands/fedit.md
  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/getting-started/mental-model.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fcontent` for exact-text confirmation only after narrowing scope, not as the first conceptual search

Applied to files:

  • site/src/content/docs/commands/fcontent.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Run `fsuite` once at the start to establish the suite-level mental model; do not re-read it

Applied to files:

  • site/src/content/docs/reference/cheatsheet.mdx
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
  • site/src/content/docs/getting-started/first-contact.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Prefer `-o paths` when piping output into another tool

Applied to files:

  • site/src/content/docs/reference/cheatsheet.mdx
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Use `fread --symbol NAME` or `--lines START:END` for targeted reading. Do not read whole files without bounds

Applied to files:

  • site/src/content/docs/commands/fread.md
  • site/src/content/docs/index.mdx
  • site/src/content/docs/getting-started/mental-model.md
📚 Learning: 2026-04-10T17:12:34.291Z
Learnt from: CR
Repo: lliWcWill/fsuite PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T17:12:34.291Z
Learning: Run `ftree --snapshot` once to establish territory and map the codebase structure. Do not rediscover the repo unless the target changes

Applied to files:

  • site/src/content/docs/commands/ftree.md
  • site/src/content/docs/getting-started/mental-model.md
🪛 LanguageTool
site/src/content/docs/commands/fmetrics.md

[grammar] ~25-~25: Ensure spelling is correct
Context: ...fmetrics` is the analytics layer. Every fsuite tool emits a telemetry record (path, ti...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

site/src/content/docs/reference/cheatsheet.mdx

[grammar] ~83-~83: Ensure spelling is correct
Context: ..."tk-mut">· --- ## ftree

ftree Territory scout · directory recon
RoleRECON
Chain position2 (scout)
Pipenot chainable (arg-based)
Outputpretty · paths · json
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~156-~156: Ensure spelling is correct
Context: ..."tk-mut">· --- ## fsearch

fsearch Filename / path search · fd-aware
RoleNARROW
Chain position3 (narrow files)
Pipeproducer (-o paths)
Outputpretty · paths · json
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~186-~186: Ensure spelling is correct
Context: ...k` | Show available backends | --- ## fcontent

fcontent Bounded content search · token-capped ripgrep
RoleNARROW
Chain position3 (narrow content)
Pipeproducer + consumer
Outputpretty · paths · json
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~214-~214: Ensure spelling is correct
Context: .../project` | Whole-word match | --- ## fmap

fmap Symbol cartography · the keystone — the gap native CLI doesn't fill
RoleKEYSTONE
Chain position4 (bridge to read)
Pipeconsumer (stdin paths)
Languages50+
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~265-~265: Ensure spelling is correct
Context: ..."tk-mut">· --- ## fread

fread Budgeted reading · symbol & line-range resolution · PDF + image media
RoleREAD
Chain position5 (read)
Pipeconsumer (--from-stdin)
MediaPDF · image · diff
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~322-~322: Ensure spelling is correct
Context: ..."tk-mut">· --- ## fedit

fedit Surgical patches · line-range · symbol-scoped · anchor-based
RolePATCH
Chain position7 (act)
Defaultdry-run (CLI)
Guard--expect · --expect-sha256
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~375-~375: Ensure spelling is correct
Context: ...ile creation or full rewrites. --- ## fbash

fbash Token-budgeted shell · classification · session state · MCP entry point
RoleEXEC
Chain positionspecialist
MCP advantageshells out to all CLI tools
Outputbudgeted · classified
> The MCP escape hatch. When you're call...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~394-394: Ensure spelling is correct
Context: ...d inside an MCP-friendly tool. --- ## fcase

fcase Investigation continuity ledger · cross-session state machine
RoleSTATE
Chain positionwraps every chain
Lifecycleinit → note → handoff → resolve
Storage/.fsuite/fcase.db
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~427-~427: Ensure spelling is correct
Context: ...json` | Export full envelope | --- ## freplay

freplay Derivation chain replay · deterministic rerun
RoleREPLAY
Chain positionspecialist
Pairs withfcase
Use forpost-mortems · regression
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~453-~453: Ensure spelling is correct
Context: ...| JSON list with step counts | --- ## fprobe

fprobe Binary / bundle inspection + patching · text tools can't reach
RoleBINARY
Chain positionspecialist branch
Use whentarget is compiled or obfuscated
Subcommandsstrings · scan · window · patch
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~481-~481: Ensure spelling is correct
Context: ...256 --decode hex` | Hex dump | --- ## fmetrics

fmetrics Telemetry analytics · tool-chain prediction
RoleLEARN
Chain positionspecialist
StorageSQLite
Use forpredict best next step
| Command | What it does | |---------|--...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

site/src/content/docs/commands/ftree.md

[style] ~25-~25: Consider using a synonym to be more concise.
Context: ...hot — see what dirs exist, what's loud (lots of files), what's lean, and where the surf...

(A_LOT_OF)

site/src/content/docs/index.mdx

[style] ~42-~42: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...output. They do not rank their results. They do not know what a token costs. **fsui...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

site/src/content/docs/story/episode-3.mdx

[grammar] ~38-~38: Ensure spelling is correct
Context: ...lob3× more often thanfsearch`. The fsuite tools were there. The agent was ignorin...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~93-~93: Ensure spelling is correct
Context: ...e/mcp/) comes in. MCP exposes every fsuite tool with a structured JSON Schema, so ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~117-~117: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...pped output. Episode 2 added structure. Episode 3 enforced adoption. Together they form...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

site/src/content/docs/story/episode-1.mdx

[style] ~52-~52: Consider a different adjective to strengthen your wording.
Context: ...cation. It worked. It also revealed the deeper issue — once you've capped the output, ...

(DEEP_PROFOUND)

site/src/content/docs/architecture/hooks.md

[style] ~78-~78: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... Exit code 0 would silently allow it. Exit code 1 would fail with the message vi...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

site/src/content/docs/architecture/mcp.md

[grammar] ~94-~94: Ensure spelling is correct
Context: ...ent off native primitives, MCP gives it fsuite as the alternative. ## Verification A...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

site/src/content/docs/getting-started/first-contact.md

[style] ~62-~62: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... a path glob, it routes to file search. Given a code identifier, it routes to symbol ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.22.1)
site/src/content/docs/architecture/telemetry.md

[warning] 104-104: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

site/src/content/docs/architecture/hooks.md

[warning] 86-86: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

site/src/content/docs/architecture/chains.md

[warning] 80-80: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 81-81: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 85-85: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 86-86: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 90-90: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 91-91: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 124-124: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 125-125: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

site/src/content/docs/architecture/mcp.md

[warning] 100-100: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Stylelint (17.9.0)
site/src/styles/custom.css

[error] 12-12: Expected "url('https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@300;400;500;600;700&display=swap')" to be "'https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@300;400;500;600;700&display=swap'" (import-notation)

(import-notation)


[error] 50-50: Expected "SFMono-Regular" to be "sfmono-regular" (value-keyword-case)

(value-keyword-case)


[error] 50-50: Expected "Menlo" to be "menlo" (value-keyword-case)

(value-keyword-case)


[error] 50-50: Expected "Consolas" to be "consolas" (value-keyword-case)

(value-keyword-case)


[error] 104-104: Expected "optimizeLegibility" to be "optimizelegibility" (value-keyword-case)

(value-keyword-case)

🔇 Additional comments (11)
site/src/content/docs/commands/fprobe.md (1)

12-53: No blockers.

site/astro.config.mjs (1)

17-21: No blockers.

site/src/content/docs/getting-started/mental-model.md (1)

8-115: No blockers.

site/src/content/docs/commands/fls.md (1)

12-97: No blockers.

site/src/components/PageTitle.astro (1)

14-26: No blocking issues.

site/src/content/docs/commands/fedit.md (1)

12-58: No blocking issues.

site/src/content/docs/reference/cheatsheet.mdx (1)

12-536: No blocking issues.

site/src/content/docs/story/lightbulb.mdx (1)

10-146: No blocking issues.

site/src/content/docs/story/episode-2.mdx (1)

10-118: No blocking issues.

site/src/content/docs/story/episode-3.mdx (1)

1-126: No blocking issues.

site/src/content/docs/story/episode-1.mdx (1)

1-101: No blocking issues.

Comment thread site/src/components/PageActions.astro Outdated
Comment thread site/src/content/docs/architecture/chains.md Outdated
Comment thread site/src/content/docs/architecture/hooks.md
Comment thread site/src/content/docs/architecture/index.mdx
Comment thread site/src/content/docs/architecture/mcp.md
Comment thread site/src/pages/[...slug].md.ts
Comment thread site/src/styles/custom.css
Comment thread site/src/styles/custom.css
Comment thread site/src/styles/custom.css
Comment thread site/src/styles/custom.css
Triaged 23 findings; fixed the real ones, flagged the false positives.

WAVE 1 — code bugs (P1/P2):
- PageActions.astro: build mdRelative with import.meta.env.BASE_URL so URLs
  survive on /fsuite/ subpath (was stripped by new URL() relative-resolve);
  client script just prepends window.location.origin now (fixes Codex P1)
- PageActions.astro: ghSourcePath now uses entry.filePath to preserve actual
  file extension — was hardcoded `.mdx` and 404'd on the 14 .md command pages
  + episode-0.md + the 4 architecture .md pages (fixes Codex P2)

WAVE 1 — accessibility/CSS:
- custom.css: html now defaults color-scheme: dark with [data-theme='light']
  override, so light theme doesn't get forced-dark native UA controls
- custom.css: added @media (prefers-reduced-motion: reduce) at the end —
  honours user motion preference, neutralizes page-actions menu fade-in and
  any future keyframe decoration
- custom.css: replaced .fs-strip-cell:nth-last-child(-n+2) mobile rule with
  conditional :nth-last-child(1) + :nth-last-child(2):nth-child(odd) so a
  5-cell layout doesn't lose the row-2/row-3 separator

WAVE 2 — doc accuracy:
- chains.md: split contradictory "Non-pipe tools" section. fread/fedit are
  now correctly classified as stdin-capable consumers; ftree/fprobe/fcase/
  freplay/fmetrics are arg-only endpoints
- hooks.md: removed 8 leftover \\{ \\} backslash escapes from JSON example
  block — was invalid JSON, copy/paste broken
- telemetry.md: ``` → ```text on the storage-tree fence (markdownlint)
- fbash.md: corrected env-var-persistence claim — only cwd + fcase/session
  state persist between calls, not exported env vars; replaced misleading
  example accordingly
- fcase.md: fread --around now targets a specific file (auth.py) instead of
  /project directory in the evidence-import example
- freplay.md: `freplay list -o json` → `freplay list auth-seam -o json` to
  match the documented `<case-slug>` requirement in the help block
- fsearch.md: explicit note that piping into fread requires `--from-stdin
  --stdin-format=paths`; the existing examples for fmap/fcontent unchanged
- ftree.md: replaced "doesn't pipe" with the accurate framing — ftree
  doesn't read from stdin (chain start, not middle filter), but does emit
  -o paths and -o json for downstream consumption
- first-contact.md: removed `| head -50` from ftree --snapshot example —
  it was truncating the JSON envelope mid-stream
- fwrite.md: relabeled "## Help output" → "## Usage notes" and clarified
  the block is the script header (set -euo pipefail visible) rather than
  runtime --help output, since fwrite's primary surface is MCP-side

WAVE 3 — cleanup:
- custom_backup.css deleted: orphan file, not loaded by Astro config

FALSE POSITIVES (verified, not fixed):
- "MCP doesn't register all 14 tools" (architecture/index.mdx + mcp.md):
  grep -nE 'server\.registerTool' mcp/index.js shows 14 distinct registrations
  for ftree/fmap/fread/fcontent/fsearch/fedit/fwrite/fcase/fmetrics/freplay/
  fprobe/fs/fls/fbash. Claim is accurate.
- "fs as pipe participant in index.mdx diagram": fs has fs-pn-entry styling
  and the undernote already explicitly states it auto-routes via fsearch +
  fcontent. Visual reposition is design-judgment, not a correctness bug.

DEFERRED:
- @import @FIRST + lowercase keywords (stylelint, not runtime)
- Self-host Geist + JetBrains Mono fonts (bigger scope, separate effort)
- pages/[...slug].md.ts homepage slug normalization to '' (current behavior
  is consistent: /fsuite/index.md route exists and PageActions targets it
  after the BASE_URL fix)

Verified: all 16 spot-checked pages (homepage, architecture trio + index,
chains, cheatsheet, first-contact, 6 commands, 2 story) return 200; dev
log clean since 16:35 fresh-start.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5a25caa5b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/content/docs/commands/fs.md
Continuation handoff for the docs/site-revamp branch:
- Where we are (rounds 1-6 + Codex triage all landed, PR #39 mergeable)
- What's next (CD's R6.5 mdx rules deliverable, then R7 visitor walkthrough)
- CD partnership pattern explained
- MDX strict-mode lessons compendium (round 2-6 hard-won knowledge)
- Dev environment + how to recover from common breakage modes
- Open questions and deferred items

Lives next to other date-stamped specs in docs/internal/specs/.
Codex P1 finding (PR #39 thread lH6b): the existing buildPage() unconditionally
overwrote every site/src/content/docs/commands/<tool>.md on every `npm run
build` (build runs gen:commands && astro build). This wiped the round-4
preambles — drone-profile cards, canonical chains, monokai terminal samples
— from CI/deploy outputs. So the deployed site would show stripped-down
pages even though the dev server (which doesn't run gen:commands)
displayed the full preambles.

Fix: make gen-commands preservation-aware. If the page already exists, read
it, find the '## Help output' marker, keep everything above it, and splice
in the regenerated help section + see-also. The auto-generated bits stay
in sync with --help output; everything above is treated as durable
hand-edited content.

Verified locally: ran the script, fmap.md kept its 5 fs-drone class
occurrences, all section headings intact (tagline H2, Canonical chains,
Terminal sample, Help output, See also), page renders 200.
@lliWcWill lliWcWill self-assigned this Apr 29, 2026
@lliWcWill
Copy link
Copy Markdown
Owner Author

Triage round complete + 2 newly-reported visual bugs to track

Triage status: 21 threads → 19 resolved (16 with commits, 3 thumbs-down on false positives), 2 left open with explanatory comments (deferred polish items).

Bucket Count Threads
✅ Fixed in a5a25ca 15 PageActions URL/extension, ftree wording, first-contact head, color-scheme, reduced-motion, mobile strip, hooks JSON, chains taxonomy, telemetry fence, fbash env, fcase fread, freplay slug, fsearch flags, fwrite help label
✅ Fixed in e566679 1 gen-commands.mjs preserves preambles above ## Help output
👎 False positive (verified, not-a-bug) 3 MCP tool count claims (×2: mcp.md + index.mdx — grep -nE "server\.registerTool" mcp/index.js returns 14 distinct registrations); fs as pipe participant (already styled fs-pn-entry + undernote disambiguates)
⏸ Deferred (kept open) 2 custom.css @import lint, [...slug].md.ts homepage normalization

Two new visual bugs surfaced after the triage push (to address in a follow-up)

While reviewing the local preview, two issues were reported that aren't in any Codex/CodeRabbit thread:

1. Page-navigation flicker on every link click. Clicking between pages in the running dev server causes a brief white/empty flash before the next page paints. Likely candidates:

  • Astro view transitions are not configured (would need <ClientRouter /> from Astro 5+ in the <head>)
  • Dev-server-only artifact from Vite HMR + content collection rehydration after R3-R6 added more page weight
  • One of the new CSS animations (page-actions menu, HUD frame, status strip) running on every route change without a stable ID

Suggest reproducing on a production astro build && astro preview to confirm whether it's dev-only or ships to deploy. If it ships, add <ClientRouter transition:animate="none" /> for stability.

2. Light theme is broken — not just inverse, white-flooded. With [data-theme='light'] active, search boxes and selected areas render as solid white instead of properly themed light backgrounds. Root cause: the CAVE theme defines all --sl-color-* tokens in :root (dark values), but the [data-theme='light'] block in custom.css:79-94 only overrides ~5 light tokens (--fs-bg-card, --fs-bg-card-hi, --fs-bg-card-on, --fs-scanline). The remaining ~30 Starlight tokens stay dark, producing the inverted-but-incomplete look.

Fix: extend the [data-theme='light'] block with full Starlight token overrides (background/foreground/hairline/selection/control colors). Alternatively, drop light mode support and force dark only via Astro config — this site is a CAVE-themed dark-first design and a half-built light theme is worse than no light theme.

Both flagged for the next polish pass; not blocking the merge of this PR.

- gen-commands.mjs preamble preservation landed in e566679 (was P1
  Codex finding lH6b; round-4 preambles were being wiped on every build)
- light theme broken in a deeper way than the kqPM color-scheme fix —
  only ~5 of ~30 Starlight tokens have light overrides, producing
  white-flood instead of a real inverse. Recommend force-dark-only
  unless the human wants to commit to a full light theme pass.
- page-navigation flicker between routes — likely missing ClientRouter
  + view transitions. Verify on production build before chasing.

PR #39 top-level comment also filed:
  #39 (comment)
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42ad05fb8d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/styles/custom.css Outdated
Codex P2 finding lXf8: the previous `:root[data-theme='light']` block only
overrode ~5 tokens (accent + fs-bg-card-* + scanline), leaving ~25 dark
Starlight tokens (--sl-color-bg, --sl-color-text, --sl-color-gray-1..7,
--sl-color-white/black, --sl-color-hairline*, --sl-color-bg-nav, etc.)
active in light mode. Result: white-flooded form controls + invisible text
on light surfaces.

Fix: full CAVE-themed light palette per Starlight's canonical
:root[data-theme='light'] pattern (verified via firecrawl scrape of
starlight.astro.build/guides/css-and-tailwind):
  - white/gray-1..7/black inverted (gray-1 = high-contrast text,
    gray-7 = lowest-contrast surface, black = #ffffff bg)
  - Background layers explicitly set to white/light (--sl-color-bg,
    --sl-color-bg-nav, --sl-color-bg-sidebar, --sl-color-bg-inline-code)
  - Text tokens explicitly set (--sl-color-text, --sl-color-text-accent,
    --sl-color-text-invert)
  - Hairlines retain CAVE green tint at light-bg-appropriate alpha
  - Accent darkened from #3aff9d (bioluminescent, unreadable on white) to
    #0a8c52 (deep forest green, AAA-ish contrast on #ffffff)

Verified all pages still 200 in dev. Production-mode toggle should now
render proper light theme instead of white-flood.
Codex thread lXf8 flagged the incomplete light-theme tokens (same bug
the user reported as 'white-flood'). Resolved with full Starlight
:root[data-theme='light'] block (verified via firecrawl scrape of
starlight.astro.build/guides/css-and-tailwind canonical pattern).

Updated handoff doc B section to reflect the fix. Page-nav flicker (A)
remains the only outstanding visual bug for follow-up.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dca597aa19

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/components/PageActions.astro Outdated
- TL;DR + git state + commit table updated to reflect all 10 commits on
  docs/site-revamp (R1-R6 + triage + 3 fixes + 3 doc updates)
- Dev server section updated with fresh PIDs (15076, 15077) and the
  .astro-cache-cleared restart at 17:28
- PR #39 thread state corrected: 22/22 resolved (was 21 in earlier write)

No code change, just keeping the handoff in sync with reality.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 707018477c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/components/PageActions.astro Outdated
THEME FORCE-DARK:
- New ThemeSelect override (HiddenThemeSelect.astro): renders nothing, hides
  the toggle UI from Starlight's nav.
- New ThemeProvider override (ForceDarkThemeProvider.astro): inline script
  pins data-theme='dark' on every load + overwrites any prior
  localStorage.starlight-theme value. is:inline so it runs before paint —
  no theme flash.
- astro.config.mjs: registered both overrides; expressiveCode dropped
  github-light from themes (only monokai now).
- The :root[data-theme='light'] block in custom.css is left as dormant
  code — re-enabling the toggle later just requires removing the two
  overrides + adding github-light back.

WHY: CAVE theme is dark-first by design. Bioluminescent green accents
(#3aff9d) only glow against deep void backgrounds; on white they're flat
and lifeless. Bloom + scanline effects don't translate. A half-built light
theme reads worse than no light theme. Removing the toggle is the honest
move.

DEFENSIVE GEN-COMMANDS:
- buildPage() now returns the existing file unchanged if it exists but
  lacks the '## Help output' marker. Previously fell through to first-time
  generation, which would WIPE any hand-customized command page (e.g.
  fwrite.md uses '## Usage notes' since its surface is MCP-only and
  doesn't have a real --help binary). Caught this when running
  gen-commands during the force-dark verification.

INCIDENTAL: fbash.md regenerated to pick up a new '--no-truncate, --full'
flag added to the fbash binary recently — natural gen-commands update.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9c6f5c63f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/[...slug].md.ts Outdated
- Updated Bug B section: light theme is now DISABLED rather than fixed
  (after verifying the rendered light theme without Dark Reader, decided
  the CAVE aesthetic doesn't translate to light surfaces; force-dark is
  more honest than half-built light theme)
- Force-dark mechanism documented: HiddenThemeSelect.astro +
  ForceDarkThemeProvider.astro overrides registered in astro.config.mjs
- Added c9c6f5c + 7070184 to commit table
- Dev environment section: HEAD updated to c9c6f5c, theme-locked note added
- Removed duplicate 'Server is already running' header from earlier sloppy edit
…ilter

Three Codex findings landed after the previous handoff was finalized.
All three are real and addressed here.

P1 — PageActions.astro:289 popup blocker (open-claude / open-chatgpt):
  Both handlers awaited fetchMarkdown() before window.open(), so the
  popup escaped user-gesture context and modern browsers veto it. Now we
  open about:blank synchronously inside the click handler, then navigate
  via popup.location.href once fetchMarkdown resolves. `noopener` is
  dropped (we need the popup ref to navigate); `popup.opener = null` is
  set manually as the security mitigation. If popup is null (blocker on)
  we surface a toast instead of failing silently.

P2 — PageActions.astro:42 ghSourcePath for section index pages:
  Starlight collapses `architecture/index.mdx` route IDs to bare
  `architecture`, so the slug-derived ghSourcePath produced
  `architecture.mdx` (404) instead of `architecture/index.mdx`. Switched
  to derive from `entry.filePath` (which preserves the actual on-disk
  path including extension) with a regex strip of the
  src/content/docs prefix. Slug-based path stays as fallback for the
  unlikely case where filePath is missing.

P2 — [...slug].md.ts:19 draft filter on raw markdown endpoint:
  getStaticPaths() pulled every docs entry without checking
  data.draft, so any page marked draft: true would still be exposed
  through /<slug>.md (Copy / View / Open-in-LLM URLs) even though
  Starlight excludes it from the rendered route. Added the filter
  predicate to getCollection('docs', ...) to mirror Starlight's
  behaviour. No drafts currently exist; this is preventive.

Verified locally: all probed pages still 200, dev server log clean,
data-gh-source on /architecture/ now ends with index.mdx.

Resolves Codex review threads:
  PRRT_kwDORCzV5M5-lf1P  (P1 popup)
  PRRT_kwDORCzV5M5-llJm  (P2 ghSourcePath)
  PRRT_kwDORCzV5M5-lynR  (P2 draft filter)
Pull post-PR38 master state (fread media engine + #32 deploy-docs
major bump) into docs/site-revamp. Resolved 5 conflicts:

- site/astro.config.mjs: kept PR39's force-dark ThemeSelect /
  ThemeProvider component overrides plus monokai-only expressiveCode
  (CAVE is dark-only by design).
- site/src/pages/[...slug].md.ts: kept PR39's draft filter on
  getStaticPaths (the actual bug fix from d9ac5c6 — master never
  filtered drafts on the raw markdown endpoint).
- site/src/components/PageActions.astro: kept PR39's d9ac5c6 version
  wholesale (popup-blocker fix via about:blank sync open, ghSourcePath
  via entry.filePath for index pages, BASE_URL trailing-slash strip).
  Master had the buggy intermediate before those fixes landed.
- site/src/styles/custom.css: kept PR39's full CAVE rebuild + the
  comprehensive Firecrawl-verified light-token block + force-dark
  color-scheme override. Master had only a short stub light theme that
  PR39 superseded; PR39 is a strict superset.
- site/src/content/docs/architecture/chains.md: synthesized — PR39's
  pipe-contract framing + 4-cmd chains + Patterns 1-5 as the base;
  appended master's unique Refactoring chain, Replay chain, and
  Measurement chain sections so the fmetrics/freplay/fedit-symbol
  workflows from PR38 don't get dropped.

Site builds clean (32 pages, 2.15s) on the resolution.

Note: site/src/styles/custom_backup.css is dev cruft from PR39's
earlier light-theme experiment and should be cleaned up in a follow-up;
left in place here so the merge is purely a 3-way resolution.
The merge in 1325843 took PR39's PageActions.astro wholesale, which
inadvertently undid PR38's accessibility cleanup. The component declared
aria-haspopup="menu", role="menu", and role="menuitem", but the script
only handles Escape close — it does not implement the W3C APG menu
keyboard contract (Enter/Space to open + focus first item, Up/Down
between items, Home/End, etc.). Misleading ARIA is worse than no ARIA
for assistive tech users.

Resolution: drop the menu roles entirely and keep aria-expanded /
aria-controls / aria-label as the open/close contract. This matches
master's pattern and the keyboard model the component actually
implements.

Also removed site/src/styles/custom_backup.css — leftover from PR39's
earlier light-theme experiment, untracked by anything in the build.

Site builds clean (32 pages, 2.14s).
Codex follow-up on f81f3e6 — that commit stripped role="menuitem" from
PageActions.astro for accessibility correctness, but the CSS in
custom.css still keyed dropdown item styling off [role="menuitem"]:

  .page-actions__menu > [role="menuitem"] { ... }
  .page-actions__menu > [role="menuitem"]:hover, ...:focus-visible { ... }

Result: hover/focus styling and the item layout silently stopped
applying once the role attribute was removed. Build was green because
CSS unmatched selectors are not errors.

Switched the three rules to .page-actions__menu > :is(button, a) which
matches the exact same 6 DOM children the role selector did (verified
in the rendered dist/commands/fbash/index.html: 5 <button>s + 1 <a>,
all data-action items inside .page-actions__menu).

Also updated the stale jsdoc comment in PageActions.astro that still
referenced "ARIA roles (menu, menuitem)" — replaced with the honest
description: real <button>s with aria-expanded for the toggle state.

Site builds clean (32 pages, 2.15s).
@lliWcWill lliWcWill merged commit 426abf6 into master Apr 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant